﻿using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Lbb.User;

namespace Lbb.Web.Mvc
{
    /// <summary>
    /// HU8控制器基类
    /// </summary>
    /// <author>Chiron</author>
    public abstract class LbbControllerBase : Controller
    {
        #region Override
        protected override void Initialize(RequestContext requestContext)
        {
            base.Initialize(requestContext);

            bool tBool;
            string tStr;

            IsAjaxRequest = Request.IsAjaxRequest();

            tStr = GetParamValue("partial");
            IsRequestPartial = (string.IsNullOrEmpty(tStr) || !bool.TryParse(tStr, out tBool) ? null : tBool as bool?) ?? IsAjaxRequest;
            ViewBag.IsRequestPartial = IsRequestPartial;
        }
        #endregion Override

        #region Fields
        /// <summary>
        /// 列表键集
        /// </summary>
        protected static string[] listKeys = new[] { 
            "pageNumber",
            "pageSize",
            "keyword",
            "orderby"
        };
        #endregion Fields

        #region Props
        /// <summary>
        /// 当前请求是否为Ajax请求.
        /// </summary>
        public bool IsAjaxRequest { get; private set; }
        /// <summary>
        /// 是否请求局部视图
        /// </summary>
        public bool IsRequestPartial { get; private set; }

        /// <summary>
        /// 当前登录的用户
        /// </summary>
        public MemberUser CurrUser
        {
            get
            {
                return _CurrUser ?? (_CurrUser = MemberUser.GetUser());
            }
        }
        private MemberUser _CurrUser;
        #endregion Props

        #region Cookie  Chrion
        /// <summary>
        /// 设置Cookie值
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        protected void SetCookie(string key, object value, string path = null)
        {
            if (string.IsNullOrEmpty(key)) throw new ArgumentNullException("key");
            var v = (value ?? "").ToString();
            if (!string.IsNullOrEmpty(v)) v = HttpUtility.UrlEncode(v);
            var cookie = Response.Cookies[key];
            cookie.Value = v;
            if (!string.IsNullOrEmpty(path)) cookie.Path = path;
        }
        /// <summary>
        /// 取得Cookie值
        /// </summary>
        /// <param name="key">键</param>
        /// <returns></returns>
        protected string GetCookie(string key)
        {
            if (string.IsNullOrEmpty(key)) throw new ArgumentNullException("key");
            var value = Request.Cookies[key] != null ? Request.Cookies[key].Value : null;
            if (!string.IsNullOrEmpty(value)) value = HttpUtility.UrlDecode(value);
            return value;
        }
        #endregion Cookie

        #region CacheArgs   Chiron
        /// <summary>
        /// 缓存参数
        /// </summary>
        /// <param name="preKey">键前辍</param>
        /// <param name="keys">键集</param>
        protected void CacheArgs(string preKey, params string[] keys)
        {
            CacheArgs(preKey, true, keys);
        }
        /// <summary>
        /// 缓存参数
        /// </summary>
        /// <param name="preKey">键前辍</param>
        /// <param name="keys">键集</param>
        protected void CacheArgs(string preKey, bool usePath, params string[] keys)
        {
            string path = null;
            if (usePath)
            {
                path = Request.Url.AbsolutePath;
                var action = RouteData.Values["action"] as string;
                if (!string.IsNullOrEmpty(action))
                {
                    path = path.Replace("/" + action, "");
                }
            }
            CacheArgs(preKey, path, keys);
        }
        /// <summary>
        /// 缓存参数
        /// </summary>
        /// <param name="preKey">键前辍</param>
        /// <param name="keys">键集</param>
        protected void CacheArgs(string preKey, string path, params string[] keys)
        {
            if (keys == null) throw new ArgumentNullException("keys");
            preKey = preKey ?? "";

            foreach (var key in keys.Where(d => !string.IsNullOrEmpty(d)))
            {
                SetCookie(preKey + key, GetParamValue(key), path);
            }
        }

        /// <summary>
        /// 取得缓存的参数
        /// </summary>
        /// <param name="preKey">键前辍</param>
        /// <param name="keys">键集</param>
        /// <returns></returns>
        protected RouteValueDictionary GetCacheArgs(string preKey, params string[] keys)
        {
            if (keys == null) throw new ArgumentNullException("keys");
            preKey = preKey ?? "";
            var args = new RouteValueDictionary();

            foreach (var key in keys.Where(d => !string.IsNullOrEmpty(d)))
            {
                args[key] = GetCookie(preKey + key);
            }
            return args;
        }

        #endregion CacheArgs

        #region Block helpers

        #region RenderBlock
        /// <summary>
        /// 渲染模块
        /// </summary>
        /// <param name="model">数据</param>
        /// <param name="template">模板</param>
        /// <param name="style">样式</param>
        /// <param name="templateDir">模板目录</param>
        protected void RenderBlock(object model, string template = null, string style = null, string templateDir = null)
        {
            templateDir = templateDir ?? "Blocks/";
            templateDir = VirtualPathUtility.AppendTrailingSlash(templateDir);
            template = template ?? GetParamValue("template");
            if (string.IsNullOrEmpty(template)) template = "Default";

            ViewBag.BlockTemplate = template;
            ViewBag.BlockStyle = style ?? GetParamValue("style");

            if (!template.Contains("/")) template = templateDir + template;

            try
            {
                View(template, model).ExecuteResult(ControllerContext);
            }
            catch (Exception ex)
            {
                if (ControllerContext.IsChildAction)
                {
                    throw;
                }
                else
                {
                    HttpContext.AddError(ex);
                }
            }
        }
        /// <summary>
        /// 渲染模块
        /// </summary>
        /// <param name="model">数据</param>
        /// <param name="template">模板</param>
        /// <param name="style">样式</param>
        /// <param name="templateDir">模板目录</param>
        /// <param name="setRouteValues">设置路由值</param>
        protected void RenderBlock<T>(DataList<T> model, string template = null, string style = null, string templateDir = null, bool setRouteValues = true)
        {
            if (setRouteValues && model != null)
            {
                model.RouteValues.template = template = template ?? GetParamValue("template");
                model.RouteValues.style = style = style ?? GetParamValue("style");
            }
            RenderBlock(model as object, template, style, templateDir ?? "ListBlocks/");
        }
        #endregion RenderBlock

        #endregion Block helpers

        #region Helpers
        /// <summary>
        /// 是否是效的值
        /// </summary>
        /// <param name="id">值</param>
        /// <returns></returns>
        protected static bool IsValidValue(ref Guid[] id)
        {
            return id != null && (id = id.Where(d => d != Guid.Empty).ToArray()).Length > 0;
        }
        /// <summary>
        /// 取得请求参数
        /// </summary>
        protected string GetParamValue(string key, string defaultValue = "")
        {
            if (string.IsNullOrEmpty(key)) return defaultValue ?? "";
            return (RouteData.Values[key] ?? RouteData.DataTokens[key] ?? Request[key] ?? defaultValue ?? "").ToString();
        }
        #endregion Helpers
    }
}
